#ifndef THREAD_FIXED_POINT_H
#define THREAD_FIXED_POINT_H

typedef int fp32_t;

/* 14 bits for fractional part. */
#define FRACTION_PART 14

/* Convert n to fixed point */
#define FP_TO_FP(N) ((fp32_t)(N << FRACTION_PART))

/* Convert x to integer (rounding toward zero) */
#define FP_GET_INT(X) (X >> FRACTION_PART)

/* Convert x to integer (rounding to nearest) */
#define FP_TO_INT(X) (X >= 0 ? ((X + (1 << (FRACTION_PART - 1))) >> FRACTION_PART) : ((X -(1 << (FRACTION_PART - 1))) >> FRACTION_PART))

/* Add x and y */
#define FP_ADD(X, Y) (X + Y)

/* Add x and n (x must be 1st arg) */
#define FP_ADD_2TYPES(X, N) (X + FP_TO_FP(N))

/* Subtract y from x */
#define FP_SUB(X, Y) (X - Y)

/* Subtract n from x (x must be 1st arg) */
#define FP_SUB_2TYPES(X, N) (X - FP_TO_FP(N))

/* Multiply x by y */
#define FP_MUL(X, Y) ((fp32_t)(((int64_t)X) * Y >> FRACTION_PART))

/* Mutiply x and n */
#define FP_MUL_2TYPES(X, N) (X * N)

/* Divide x by y */
#define FP_DIV(X, Y) ((fp32_t)((((int64_t)X) << FRACTION_PART) / Y))

/* Subtract x by n (x must be 1st arg) */
#define FP_DIV_2TYPES(X, N) (X / N)

#endif